package com.sunwayhorizo.health.business.clinic.emr.document.query;

import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.jboss.seam.annotations.Name;

import com.sunwayhorizo.health.common.ListUtil;
import com.sunwayhorizo.health.common.StrUtil;
import com.sunwayhorizo.health.hl7.common.Hl7Exception;
import com.sunwayhorizo.health.hl7.persistent.RimCoreEds;
import com.sunwayhorizo.health.hl7.rim.Observation;
import com.sunwayhorizo.health.hl7.vocabulary.ActStatus;
import com.sunwayhorizo.health.hl7.vocabulary.ParticipationType;

@Name("DocumentQuery")
@Stateless
public class DocumentQuery implements DocumentQueryLocal
{

    @PersistenceContext(unitName = "sunwayhealth")
    private EntityManager em;


    @SuppressWarnings("unchecked")
    public List<Object> findActIdByTempClassRoleId(String emrClassRoleId) throws Hl7Exception
    {
        StringBuilder jpql = new StringBuilder();
        jpql.append("select p.participationAct.actId from ActParticipation p ");
        jpql.append(" where ");
        jpql.append(" p.typeCode = 'HLD' ");
        jpql.append(" and ");
        jpql.append(" p.roleParticipation.roleId = ");
        jpql.append(emrClassRoleId);
        List<Object> objs = em.createQuery(jpql.toString()).getResultList();
        return objs;
    }


    @SuppressWarnings("rawtypes")
    public List findEmrByPatientID(String patientID, String classCode,String patientNum) throws Hl7Exception
    {
        StringBuilder jpql = new StringBuilder();
        jpql.append("select distinct(e.actId), e.titleTxt,e.medicalRecordsState,e.statusCode,e.codeEtsId,e.createdBy,e.creationDate,e.levelCodeEtsId,e.dcStorageCodeEtsId,e.dcCompletionCodeEtsId from  Document e");
        jpql.append(" left join e.prtcptnsActList p");
        jpql.append(" where e.classCode='DOCCLIN' and e.statusCode='" + ActStatus.ACTIVE.code().toString() + "' ");
        if (StrUtil.isNotEmpty(classCode))
        {
            jpql.append(" and e.codeEtsId=?1 ");
        }
        if (StrUtil.isNotEmpty(patientID))
        {
            jpql.append(" and p.roleParticipation.roleId=?2 ");
        }
        if (StrUtil.isNotEmpty(patientNum))
        {
            jpql.append(" and  p.sequenceNum=?3");
        }
        jpql.append(" order by e.actId asc");
        Query query = em.createQuery(jpql.toString());
        if (StrUtil.isNotEmpty(classCode))
        {
            query.setParameter(1, classCode);
        }
        if (StrUtil.isNotEmpty(patientID))
        {
            query.setParameter(2, Long.valueOf(patientID));
        }
        if (StrUtil.isNotEmpty(patientNum))
        {
            query.setParameter(3, Long.valueOf(patientNum));
        }
        List doc = query.getResultList();
        return doc;
    }

   //此方法业务有变动，需要调整
    @SuppressWarnings("unchecked")
    public List<RimCoreEds> findInPatientMacroInfoByPatientId(String patientId,String patientNum) throws Hl7Exception
    {
        StringBuilder jbql = new StringBuilder();
        jbql.append(" select p.rimCoreEdsNoteTextEdId from ActParticipation p ");
        jbql.append(" where p.typeCode='" + ParticipationType.RCT.code().toString()+ "'");
        if (StrUtil.isNotEmpty(patientId))
        {
            jbql.append(" and p.roleParticipation.roleId=?1");
        }
        if (StrUtil.isNotEmpty(patientNum))
        {
            jbql.append(" and  p.sequenceNum=?2");
        }
        Query query = em.createQuery(jbql.toString());
        if (StrUtil.isNotEmpty(patientId))
        {
            query.setParameter(1, Long.parseLong(patientId));
        }
        if (StrUtil.isNotEmpty(patientNum))
        {
            query.setParameter(2, Long.parseLong(patientNum));
        }
        List<RimCoreEds> list = query.getResultList();
        return list;
    }
    
    @SuppressWarnings("unchecked")
    public List<Observation> findDiagnosisByPatientId(String patientId,String patientNum) throws Hl7Exception
    {
        if(StrUtil.isEmpty(patientId) || StrUtil.isEmpty(patientNum)) return null;
        StringBuilder jbql = new StringBuilder();
        jbql.append(" select doc.actId from Document doc ");
        jbql.append(" left join doc.prtcptnsActList part ");
        jbql.append(" where doc.classCode='DOCCLIN' and part.typeCode='RCT'" );
        jbql.append(" and part.roleParticipation.roleId=");
        jbql.append(patientId);
        jbql.append(" and  part.sequenceNum=");
        jbql.append(Long.valueOf((StrUtil.isNotEmpty(patientNum) ? patientNum : "1")));
        List<Long> rctList = em.createQuery(jbql.toString()).getResultList();
        if(ListUtil.isNotEmpty(rctList))
        {
            StringBuilder jpql = new StringBuilder();
            jpql.append(" select obs from Observation obs ");
            jpql.append(" where obs.actId in ");
            jpql.append(" (");
            jpql.append(" select r.targetAct.actId from ActRelationship r where ( ");
            for(int i = 0 ; i < rctList.size() ; i++ )
            {
                Long actId = (Long)rctList.get(i);
                if( i < rctList.size()-1 )
                {
                    jpql.append(" r.sourceAct.actId="+actId+" or " );
                }else
                {
                    jpql.append(" r.sourceAct.actId="+actId);
                }
            }
            jpql.append(" )");
            jpql.append(" ) order by obs.titleTxt asc ");
            List<Observation> list = em.createQuery(jpql.toString()).getResultList();
            return list;
        }
       return null;
    }
    
    @SuppressWarnings("unchecked")
    public List<Long> findAlreadyWriteDocByPatientId(String patienId,String patientNum) throws Hl7Exception
    {
        StringBuilder jpql = new StringBuilder();
        jpql.append(" select doc.actId from Document doc left join doc.prtcptnsActList part ");
        jpql.append(" where doc.classCode='DOCCLIN' and doc.codeEtsId!='D' and part.typeCode='RCT'");
        jpql.append(" and part.roleParticipation.roleId="+patienId);
        jpql.append(" and part.sequenceNum="+patientNum);
        List<Long> rctList = em.createQuery(jpql.toString()).getResultList();
        return rctList;
    }
    
    @SuppressWarnings("unchecked")
    public List<Long> findAlreadySignatureDocByPatientId(String patienId,String patientNum) throws Hl7Exception
    {
        //组装已经书写的动作id语句
        String cond = " select doc.actId from Document doc left join doc.prtcptnsActList part where doc.classCode='DOCCLIN' and doc.codeEtsId!='D' and part.typeCode='RCT' and part.roleParticipation.roleId="+patienId+" and part.sequenceNum="+patientNum;
        //判断患者一共签名了多少个文件
        StringBuilder jpql = new StringBuilder();
        jpql.append(" select d.actId from Document d left join d.prtcptnsActList p ");
        jpql.append(" where d.classCode='DOCCLIN' and p.typeCode='ESC'");
        jpql.append(" and p.participationAct.actId in ");
        jpql.append(" ("+cond+")");
        List<Long> escList = em.createQuery(jpql.toString()).getResultList();
        return escList;
    }
    
    @SuppressWarnings("rawtypes")
    public List findFirstMedicalActIdByPatientId(String patientId,String patientNum) throws Hl7Exception
    {
        if(StrUtil.isEmpty(patientId)) return null;
        StringBuilder jbql = new StringBuilder();
        jbql.append(" select doc.actId from Document doc left join doc.prtcptnsActList part ");
        jbql.append(" where doc.classCode='DOCCLIN' and doc.codeEtsId='CA' and doc.levelCodeEtsId='C01'");
        if (StrUtil.isNotEmpty(patientId))
        {
            jbql.append(" and part.roleParticipation.roleId=?1");
        }
        if (StrUtil.isNotEmpty(patientNum))
        {
            jbql.append(" and part.sequenceNum=?2");
        }
        Query query = em.createQuery(jbql.toString());
        if (StrUtil.isNotEmpty(patientId))
        {
            query.setParameter(1, Long.valueOf(patientId));
        }
        if (StrUtil.isNotEmpty(patientNum))
        {
            query.setParameter(2, Long.valueOf(patientNum));
        }
        List list = query.getResultList();
        return list;
    }
}
